home *** CD-ROM | disk | FTP | other *** search
- /* "Face" primitives
- Copyright (C) 1994 Free Software Foundation, Inc.
- Copyright (C) 1995 Board of Trustees, University of Illinois
- Copyright (C) 1995 Ben Wing
-
- This file is part of XEmacs.
-
- XEmacs is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- XEmacs is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License
- along with XEmacs; see the file COPYING. If not, write to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Synched up with: Not in FSF. */
-
- /* Written by Chuck Thompson and Ben Wing,
- based loosely on old face code by Jamie Zawinski. */
-
- #include <config.h>
- #include "lisp.h"
-
- #include "buffer.h"
- #include "device.h"
- #include "elhash.h"
- #include "extents.h"
- #include "faces.h"
- #include "frame.h"
- #include "glyphs.h"
- #include "hash.h"
- #include "objects.h"
- #include "specifier.h"
- #include "window.h"
-
- #ifdef HAVE_X_WINDOWS
- #include "device-x.h"
- #include "frame-x.h"
- #include "objects-x.h"
- #include "EmacsFrame.h"
- #endif /* HAVE_X_WINDOWS */
-
- #ifdef HAVE_NEXTSTEP
- #include "device-ns.h"
- #include "frame-ns.h"
- #include "objects-ns.h"
- #endif /* HAVE_NEXTSTEP */
-
- /* Qfont, Qdoc_string defined in general.c */
- Lisp_Object Qface, Qfacep;
- Lisp_Object Qforeground, Qbackground, Qdisplay_table;
- /* Qhighlight, Qreverse defined in general.c */
- Lisp_Object Qbackground_pixmap, Qunderline, Qdim;
- Lisp_Object Qblinking;
-
- Lisp_Object Qinit_face_from_resources;
- Lisp_Object Qinit_frame_faces;
- Lisp_Object Qinit_device_faces;
- Lisp_Object Qinit_global_faces;
- Lisp_Object Qinit_faces;
-
- /* These faces are used directly internally. We use these variables
- to be able to reference them directly and save the overhead of
- calling Ffind_face. */
- Lisp_Object Vdefault_face, Vmodeline_face, Vhighlight_face;
- Lisp_Object Vleft_margin_face, Vright_margin_face;
-
- /* Qdefault, Qhighlight defined in general.c */
- Lisp_Object Qmodeline, Qleft_margin, Qright_margin;
-
- /* In the old implementation Vface_list was a list of the face names,
- not the faces themselves. We now distinguish between permanent and
- temporary faces. Permanent faces are kept in a regular hash table,
- temporary faces in a weak hash table. */
- Lisp_Object Vpermanent_faces_cache;
- Lisp_Object Vtemporary_faces_cache;
-
-
- static Lisp_Object mark_face (Lisp_Object, void (*) (Lisp_Object));
- static void print_face (Lisp_Object, Lisp_Object, int);
- static int face_equal (Lisp_Object, Lisp_Object, int depth);
- static unsigned long face_hash (Lisp_Object obj, int depth);
- static int face_getprop (Lisp_Object obj, Lisp_Object prop,
- Lisp_Object *value_out);
- static int face_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value);
- static int face_remprop (Lisp_Object obj, Lisp_Object prop);
- static Lisp_Object face_props (Lisp_Object obj);
- DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("face", face,
- mark_face, print_face, 0, face_equal,
- face_hash, face_getprop,
- face_putprop, face_remprop,
- face_props, struct Lisp_Face);
-
- static Lisp_Object
- mark_face (Lisp_Object obj, void (*markobj) (Lisp_Object))
- {
- struct Lisp_Face *face = XFACE (obj);
-
- ((markobj) (face->name));
- ((markobj) (face->doc_string));
-
- ((markobj) (face->foreground));
- ((markobj) (face->background));
- ((markobj) (face->font));
- ((markobj) (face->display_table));
- ((markobj) (face->background_pixmap));
- ((markobj) (face->underline));
- ((markobj) (face->highlight));
- ((markobj) (face->dim));
- ((markobj) (face->blinking));
- ((markobj) (face->reverse));
-
- return (face->plist);
- }
-
- static void
- print_face (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
- {
- struct Lisp_Face *face = XFACE (obj);
-
- if (print_readably)
- error ("printing unreadable object #<face %s>",
- string_data (XSYMBOL (face->name)->name));
-
- write_c_string ("#<face ", printcharfun);
- print_internal (face->name, printcharfun, 1);
- if (!NILP (face->doc_string))
- {
- write_c_string (" ", printcharfun);
- print_internal (face->doc_string, printcharfun, 1);
- }
- write_c_string (">", printcharfun);
- }
-
- /* Faces are equal if all of their display attributes are equal. We
- don't compare names or doc-strings, because that would make equal
- be eq.
-
- This isn't concerned with "unspecified" attributes, that's what
- #'face-differs-from-default-p is for. */
- static int
- face_equal (Lisp_Object o1, Lisp_Object o2, int depth)
- {
- struct Lisp_Face *f1 = XFACE (o1);
- struct Lisp_Face *f2 = XFACE (o2);
-
- depth++;
-
- if (!internal_equal (f1->foreground, f2->foreground, depth) ||
- !internal_equal (f1->background, f2->background, depth) ||
- !internal_equal (f1->font, f2->font, depth) ||
- !internal_equal (f1->display_table, f2->display_table, depth) ||
- !internal_equal (f1->background_pixmap, f2->background_pixmap, depth) ||
- !internal_equal (f1->underline, f2->underline, depth) ||
- !internal_equal (f1->highlight, f2->highlight, depth) ||
- !internal_equal (f1->dim, f2->dim, depth) ||
- !internal_equal (f1->blinking, f2->blinking, depth) ||
- !internal_equal (f1->reverse, f2->reverse, depth) ||
- plists_differ (f1->plist, f2->plist, depth + 1))
- return 0;
-
- return 1;
- }
-
- static unsigned long
- face_hash (Lisp_Object obj, int depth)
- {
- struct Lisp_Face *f = XFACE (obj);
-
- depth++;
-
- /* No need to hash all of the elements; that would take too long.
- Just hash the most common ones. */
- return HASH3 (internal_hash (f->foreground, depth),
- internal_hash (f->background, depth),
- internal_hash (f->font, depth));
- }
-
- static int
- face_getprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object *value_out)
- {
- struct Lisp_Face *f = XFACE (obj);
-
- #define FROB(propprop) \
- do { \
- if (EQ (prop, Q##propprop)) \
- { \
- *value_out = f->propprop; \
- return 1; \
- } \
- } while (0)
-
- FROB (foreground);
- FROB (background);
- FROB (font);
- FROB (display_table);
- FROB (background_pixmap);
- FROB (underline);
- FROB (highlight);
- FROB (dim);
- FROB (blinking);
- FROB (reverse);
-
- #undef FROB
-
- return internal_getf (f->plist, prop, value_out);
- }
-
- static int
- face_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value)
- {
- struct Lisp_Face *f = XFACE (obj);
-
- #define FROB(propprop) \
- do { \
- if (EQ (prop, Q##propprop)) \
- return 0; \
- } while (0)
-
- FROB (foreground);
- FROB (background);
- FROB (font);
- FROB (display_table);
- FROB (background_pixmap);
- FROB (underline);
- FROB (highlight);
- FROB (dim);
- FROB (blinking);
- FROB (reverse);
-
- #undef FROB
-
- if (EQ (prop, Qdoc_string))
- {
- if (!NILP (value))
- CHECK_STRING (value, 0);
- f->doc_string = value;
- return 1;
- }
-
- internal_putf (&f->plist, prop, value);
- return 1;
- }
-
- static int
- face_remprop (Lisp_Object obj, Lisp_Object prop)
- {
- struct Lisp_Face *f = XFACE (obj);
-
- #define FROB(propprop) \
- do { \
- if (EQ (prop, Q##propprop)) \
- return -1; \
- } while (0)
-
- FROB (foreground);
- FROB (background);
- FROB (font);
- FROB (display_table);
- FROB (background_pixmap);
- FROB (underline);
- FROB (highlight);
- FROB (dim);
- FROB (blinking);
- FROB (reverse);
-
- #undef FROB
-
- if (EQ (prop, Qdoc_string))
- {
- f->doc_string = Qnil;
- return 1;
- }
-
- return internal_remprop (&f->plist, prop);
- }
-
- static Lisp_Object
- face_props (Lisp_Object obj)
- {
- struct Lisp_Face *f = XFACE (obj);
- Lisp_Object result = Qnil;
-
- #define FROB(propprop) \
- do { \
- result = Fcons (f->propprop, Fcons (Q##propprop, result)); \
- } while (0)
-
- /* backwards order; we reverse it below */
- FROB (reverse);
- FROB (blinking);
- FROB (dim);
- FROB (highlight);
- FROB (underline);
- FROB (background_pixmap);
- FROB (display_table);
- FROB (font);
- FROB (background);
- FROB (foreground);
-
- #undef FROB
- return nconc2 (Fnreverse (result), Fcopy_sequence (f->plist));
- }
-
-
- /*****************************************************************************
- utility functions
- ****************************************************************************/
-
- static void
- reset_face (struct Lisp_Face *f)
- {
- f->name = Qnil;
- f->doc_string = Qnil;
- f->dirty = 0;
- f->foreground = Qnil;
- f->background = Qnil;
- f->font = Qnil;
- f->display_table = Qnil;
- f->background_pixmap = Qnil;
- f->underline = Qnil;
- f->highlight = Qnil;
- f->dim = Qnil;
- f->blinking = Qnil;
- f->reverse = Qnil;
- f->plist = Qnil;
- }
-
- static struct Lisp_Face *
- allocate_face (void)
- {
- struct Lisp_Face *result =
- alloc_lcrecord (sizeof (struct Lisp_Face), lrecord_face);
-
- reset_face (result);
- return result;
- }
-
-
- /* We store the faces in hash tables with the names as the key and the
- actual face object as the value. Occasionally we need to use them
- in a list format. These routines provide us with that. */
- struct face_list_closure
- {
- Lisp_Object *face_list;
- };
-
- static void
- add_face_to_list_mapper (CONST void *hash_key, void *hash_contents,
- void *face_list_closure)
- {
- /* This function can GC */
- Lisp_Object key, contents;
- Lisp_Object *face_list;
- struct face_list_closure *fcl = face_list_closure;
- CVOID_TO_LISP (key, hash_key);
- VOID_TO_LISP (contents, hash_contents);
- face_list = fcl->face_list;
-
- *face_list = Fcons (XFACE (contents)->name, *face_list);
- }
-
- static Lisp_Object
- faces_list_internal (Lisp_Object list)
- {
- Lisp_Object face_list = Qnil;
- struct gcpro gcpro1;
- struct face_list_closure face_list_closure;
-
- GCPRO1 (face_list);
- face_list_closure.face_list = &face_list;
- elisp_maphash (add_face_to_list_mapper, list, &face_list_closure);
- UNGCPRO;
-
- return face_list;
- }
-
- static Lisp_Object
- permanent_faces_list (void)
- {
- return faces_list_internal (Vpermanent_faces_cache);
- }
-
- static Lisp_Object
- temporary_faces_list (void)
- {
- return faces_list_internal (Vtemporary_faces_cache);
- }
-
-
- static void
- mark_face_as_clean_mapper (CONST void *hash_key, void *hash_contents,
- void *flag_closure)
- {
- /* This function can GC */
- Lisp_Object key, contents;
- int *flag = flag_closure;
- CVOID_TO_LISP (key, hash_key);
- VOID_TO_LISP (contents, hash_contents);
- XFACE (contents)->dirty = *flag;
- }
-
- static void
- mark_all_faces_internal (int flag)
- {
- elisp_maphash (mark_face_as_clean_mapper, Vpermanent_faces_cache, &flag);
- elisp_maphash (mark_face_as_clean_mapper, Vtemporary_faces_cache, &flag);
- }
-
- void
- mark_all_faces_as_clean (void)
- {
- mark_all_faces_internal (0);
- }
-
- /* #### OBSOLETE ME, PLEASE. Maybe. Maybe this is just as good as
- any other solution. */
- struct face_inheritance_closure
- {
- Lisp_Object face;
- Lisp_Object property;
- };
-
- static void
- update_inheritance_mapper_internal (Lisp_Object cur_face,
- Lisp_Object inh_face,
- Lisp_Object property)
- {
- /* #### fix this function */
- Lisp_Object elt = Qnil;
- struct gcpro gcpro1;
-
- GCPRO1 (elt);
-
- for (elt = FACE_PROPERTY_SPEC_LIST (cur_face, property, Qall);
- !NILP (elt);
- elt = XCDR (elt))
- {
- Lisp_Object locale, values;
-
- locale = XCAR (XCAR (elt));
- values = XCDR (XCAR (elt));
-
- for (; !NILP (values); values = XCDR (values))
- {
- Lisp_Object tag = XCAR (XCAR (values));
- Lisp_Object value = XCDR (XCAR (values));
- if (VECTORP (value) && XVECTOR (value)->size)
- {
- if (EQ (Ffind_face (vector_data (XVECTOR (value))[0]), inh_face))
- {
- /* #### This should probably be changed. We just want
- to mark the face as dirty and reset its specifier
- instance list. */
- SET_FACE_PROPERTY (cur_face, property, value, locale, tag,
- Qnil);
- }
- }
- }
- }
-
- UNGCPRO;
- }
-
- static void
- update_face_inheritance_mapper (CONST void *hash_key, void *hash_contents,
- void *face_inheritance_closure)
- {
- Lisp_Object key, contents;
- struct face_inheritance_closure *fcl = face_inheritance_closure;
-
- CVOID_TO_LISP (key, hash_key);
- VOID_TO_LISP (contents, hash_contents);
-
- if (EQ (fcl->property, Qfont))
- {
- update_inheritance_mapper_internal (contents, fcl->face, Qfont);
- }
- else if (EQ (fcl->property, Qforeground)
- || EQ (fcl->property, Qbackground))
- {
- update_inheritance_mapper_internal (contents, fcl->face, Qforeground);
- update_inheritance_mapper_internal (contents, fcl->face, Qbackground);
- }
- else if (EQ (fcl->property, Qunderline)
- || EQ (fcl->property, Qhighlight)
- || EQ (fcl->property, Qdim)
- || EQ (fcl->property, Qblinking)
- || EQ (fcl->property, Qreverse))
- {
- update_inheritance_mapper_internal (contents, fcl->face, Qunderline);
- update_inheritance_mapper_internal (contents, fcl->face, Qhighlight);
- update_inheritance_mapper_internal (contents, fcl->face, Qdim);
- update_inheritance_mapper_internal (contents, fcl->face, Qblinking);
- update_inheritance_mapper_internal (contents, fcl->face, Qreverse);
- }
- }
-
- static void
- update_faces_inheritance (Lisp_Object face, Lisp_Object property)
- {
- struct face_inheritance_closure face_inheritance_closure;
- struct gcpro gcpro1, gcpro2;
-
- GCPRO2 (face, property);
- face_inheritance_closure.face = face;
- face_inheritance_closure.property = property;
-
- elisp_maphash (update_face_inheritance_mapper, Vpermanent_faces_cache,
- &face_inheritance_closure);
- elisp_maphash (update_face_inheritance_mapper, Vtemporary_faces_cache,
- &face_inheritance_closure);
-
- UNGCPRO;
- }
-
-
- DEFUN ("facep", Ffacep, Sfacep, 1, 1, 0,
- "Return non-nil if OBJECT is a face.")
- (object)
- Lisp_Object object;
- {
- return (FACEP (object) ? Qt : Qnil);
- }
-
- DEFUN ("find-face", Ffind_face, Sfind_face, 1, 1, 0,
- "Retrieve the face of the given name.\n\
- If FACE-OR-NAME is a face object, it is simply returned.\n\
- Otherwise, FACE-OR-NAME should be a symbol. If there is no such face,\n\
- nil is returned. Otherwise the associated face object is returned.")
- (face_or_name)
- Lisp_Object face_or_name;
- {
- Lisp_Object retval;
-
- if (FACEP (face_or_name))
- return face_or_name;
- CHECK_SYMBOL (face_or_name, 0);
-
- /* Check if the name represents a permanent face. */
- retval = Fgethash (face_or_name, Vpermanent_faces_cache, Qnil);
- if (!NILP (retval))
- return retval;
-
- /* Check if the name represents a temporary face. */
- return Fgethash (face_or_name, Vtemporary_faces_cache, Qnil);
- }
-
- DEFUN ("get-face", Fget_face, Sget_face, 1, 1, 0,
- "Retrieve the face of the given name.\n\
- Same as `find-face' except an error is signalled if there is no such\n\
- face instead of returning nil.")
- (name)
- Lisp_Object name;
- {
- Lisp_Object face = Ffind_face (name);
-
- if (NILP (face))
- signal_simple_error ("No such face", name);
- return face;
- }
-
- DEFUN ("face-name", Fface_name, Sface_name, 1, 1, 0,
- "Return the name of the given face.")
- (face)
- Lisp_Object face;
- {
- return (XFACE (Fget_face (face))->name);
- }
-
- void
- face_font_metric_info (Lisp_Object face, Lisp_Object domain,
- struct font_metric_info *fm)
- {
- struct device *d = XDEVICE (DFW_DEVICE (domain));
-
- DEVMETH (d, font_metric_info, (d, FACE_FONT (face, domain),
- fm));
- }
-
- /* These values are retrieved so often that we make a special
- function.
-
- #### Should this perhaps look in the face-cache-element cache
- for the domain, esp. if it is a window (as is usually the case)? */
-
- void
- default_face_height_and_width (Lisp_Object domain,
- int *height, int *width)
- {
- struct device *d = XDEVICE (DFW_DEVICE (domain));
- struct font_metric_info fm;
-
- DEVMETH (d, font_metric_info, (d, FACE_FONT (Vdefault_face, domain),
- &fm));
- *height = fm.height;
- *width = fm.width;
- }
-
- DEFUN ("face-ascent", Fface_ascent, Sface_ascent, 1, 2, 0,
- "Return the ascent portion of the FACE's height in the given DOMAIN.\n\
- If DOMAIN is nil, it will be determined from the selected window.")
- (face, domain)
- Lisp_Object face, domain;
- {
- struct font_metric_info fm;
-
- face = Fget_face (face);
- domain = decode_domain (domain);
-
- face_font_metric_info (face, domain, &fm);
- return (make_number (fm.ascent));
- }
-
- DEFUN ("face-descent", Fface_descent, Sface_descent, 1, 2, 0,
- "Return the descent portion of the FACE's height in the given DOMAIN.\n\
- If DOMAIN is nil, it will be determined from the selected window.")
- (face, domain)
- Lisp_Object face, domain;
- {
- struct font_metric_info fm;
-
- face = Fget_face (face);
- domain = decode_domain (domain);
-
- face_font_metric_info (face, domain, &fm);
- return (make_number (fm.descent));
- }
-
- DEFUN ("face-width", Fface_width, Sface_width, 1, 2, 0,
- "Return the width of FACE in the given DOMAIN.\n\
- If DOMAIN is nil, it will be determined from the selected window.")
- (face, domain)
- Lisp_Object face, domain;
- {
- struct font_metric_info fm;
-
- face = Fget_face (face);
- domain = decode_domain (domain);
-
- face_font_metric_info (face, domain, &fm);
- return (make_number (fm.width));
- }
-
- DEFUN ("face-list", Fface_list, Sface_list, 0, 1, 0,
- "Return a list of the names of all defined faces.\n\
- If TEMPORARY is nil, only the permanent faces are included.\n\
- If it is t, only the temporary faces are included. If it is any\n\
- other non-nil value both permanent and temporary are included.")
- (temporary)
- Lisp_Object temporary;
- {
- Lisp_Object face_list = Qnil;
-
- /* Added the permanent faces, if requested. */
- if (NILP (temporary) || !EQ (Qt, temporary))
- face_list = permanent_faces_list ();
-
- if (!NILP (temporary))
- {
- struct gcpro gcpro1;
- GCPRO1 (face_list);
- face_list = nconc2 (face_list, temporary_faces_list ());
- UNGCPRO;
- }
-
- return face_list;
- }
-
- DEFUN ("extent-face", Fextent_face, Sextent_face, 1, 1, 0,
- "Return the name of the face in which EXTENT is displayed, or nil\n\
- if the extent's face is unspecified.")
- (extent)
- Lisp_Object extent;
- {
- CHECK_EXTENT (extent, 0);
-
- if (NILP (extent_face (XEXTENT (extent))))
- return Qnil;
- else
- return (XFACE (extent_face (XEXTENT (extent)))->name);
- }
-
- DEFUN ("set-extent-face", Fset_extent_face, Sset_extent_face, 2, 2, 0,
- "Make the given EXTENT have the graphic attributes specified by FACE.")
- (extent, face)
- Lisp_Object extent, face;
- {
- EXTENT e;
-
- CHECK_EXTENT (extent, 0);
- e = XEXTENT (extent);
-
- if (!NILP (face))
- face = Fget_face (face);
-
- set_extent_face (e, face);
-
- return face;
- }
-
- DEFUN ("make-face", Fmake_face, Smake_face, 1, 3, 0,
- "Defines and returns a new FACE described by DOC-STRING.\n\
- You can modify the font, color, etc of a face with the set-face- functions.\n\
- If the face already exists, it is unmodified.\n\
- If TEMPORARY is non-nil, this face will cease to exist if not in use.")
- (name, doc_string, temporary)
- Lisp_Object name, doc_string, temporary;
- {
- /* This function can GC if initialized is non-zero */
- struct Lisp_Face *f;
- Lisp_Object face;
-
- CHECK_SYMBOL (name, 0);
- if (!NILP (doc_string))
- CHECK_STRING (doc_string, 0);
-
- face = Ffind_face (name);
- if (!NILP (face))
- return face;
-
- f = allocate_face ();
- XSETFACE (face, f);
-
- f->name = name;
- f->doc_string = doc_string;
- f->foreground = Fmake_specifier (Qcolor);
- set_color_attached_to (f->foreground, face, Qforeground);
- f->background = Fmake_specifier (Qcolor);
- set_color_attached_to (f->background, face, Qbackground);
- f->font = Fmake_specifier (Qfont);
- set_font_attached_to (f->font, face, Qfont);
- f->background_pixmap = Fmake_specifier (Qimage);
- set_image_attached_to (f->background_pixmap, face, Qbackground_pixmap);
- /* #### need a special display-table specifier */
- f->display_table = Fmake_specifier (Qgeneric);
- f->underline = Fmake_specifier (Qface_boolean);
- set_face_boolean_attached_to (f->underline, face, Qunderline);
- f->highlight = Fmake_specifier (Qface_boolean);
- set_face_boolean_attached_to (f->highlight, face, Qhighlight);
- f->dim = Fmake_specifier (Qface_boolean);
- set_face_boolean_attached_to (f->dim, face, Qdim);
- f->blinking = Fmake_specifier (Qface_boolean);
- set_face_boolean_attached_to (f->blinking, face, Qblinking);
- f->reverse = Fmake_specifier (Qface_boolean);
- set_face_boolean_attached_to (f->reverse, face, Qreverse);
- if (!NILP (Vdefault_face))
- {
- /* If the default face has already been created, set it as
- the default fallback specifier for all the specifiers we
- just created. This implements the standard "all faces
- inherit from default" behavior. */
- set_specifier_fallback (f->foreground,
- Fget (Vdefault_face, Qforeground, Qunbound));
- set_specifier_fallback (f->background,
- Fget (Vdefault_face, Qbackground, Qunbound));
- set_specifier_fallback (f->font,
- Fget (Vdefault_face, Qfont, Qunbound));
- set_specifier_fallback (f->background_pixmap,
- Fget (Vdefault_face, Qbackground_pixmap,
- Qunbound));
- set_specifier_fallback (f->display_table,
- Fget (Vdefault_face, Qdisplay_table, Qunbound));
- set_specifier_fallback (f->underline,
- Fget (Vdefault_face, Qunderline, Qunbound));
- set_specifier_fallback (f->highlight,
- Fget (Vdefault_face, Qhighlight, Qunbound));
- set_specifier_fallback (f->dim,
- Fget (Vdefault_face, Qdim, Qunbound));
- set_specifier_fallback (f->blinking,
- Fget (Vdefault_face, Qblinking, Qunbound));
- set_specifier_fallback (f->reverse,
- Fget (Vdefault_face, Qreverse, Qunbound));
- }
-
- /* Add the face to the appropriate list. */
- if (NILP (temporary))
- Fputhash (name, face, Vpermanent_faces_cache);
- else
- Fputhash (name, face, Vtemporary_faces_cache);
-
- if (initialized)
- {
- struct gcpro gcpro1, gcpro2;
-
- GCPRO2 (name, face);
- call1 (Qinit_face_from_resources, name);
- UNGCPRO;
- }
-
- return face;
- }
-
-
- /*****************************************************************************
- initialization code
- ****************************************************************************/
-
- void
- init_global_faces (struct device *d)
- {
- /* When making the initial terminal device, there is no Lisp code
- loaded, so we can't do this. */
- if (initialized)
- {
- call_critical_lisp_code (d, Qinit_global_faces, Qnil);
- }
- }
-
- void
- init_device_faces (struct device *d)
- {
- /* When making the initial terminal device, there is no Lisp code
- loaded, so we can't do this. */
- if (initialized)
- {
- Lisp_Object tdevice;
- XSETDEVICE (tdevice, d);
- call_critical_lisp_code (d, Qinit_device_faces, tdevice);
- }
- }
-
- void
- init_frame_faces (struct frame *frm)
- {
- /* When making the initial terminal device, there is no Lisp code
- loaded, so we can't do this. */
- if (initialized)
- {
- Lisp_Object tframe;
- XSETFRAME (tframe, frm);
-
- /* DO NOT change the selected frame here. If the debugger goes off
- it will try and display on the frame being created, but it is not
- ready for that yet and a horrible death will occur. Any random
- code depending on the selected-frame as an implicit arg should be
- tracked down and shot. For the benefit of the one known,
- xpm-color-symbols, make-frame sets the variable
- Vframe_being_created to the frame it is making and sets it to nil
- when done. Internal functions that this could trigger which are
- currently depending on selected-frame should use this instead. It
- is not currently visible at the lisp level. */
- call_critical_lisp_code (XDEVICE (FRAME_DEVICE (frm)),
- Qinit_frame_faces, tframe);
- }
- }
-
-
- /*****************************************************************************
- face cache element functions
- ****************************************************************************/
- void
- mark_face_cache_elements (face_cache_element_dynarr *elements,
- void (*markobj) (Lisp_Object))
- {
- int elt;
-
- if (!elements)
- return;
-
- for (elt = 0; elt < Dynarr_length (elements); elt++)
- {
- struct face_cache_element *inst = Dynarr_atp (elements, elt);
-
- ((markobj) (inst->face));
- ((markobj) (inst->foreground));
- ((markobj) (inst->background));
- ((markobj) (inst->font));
- ((markobj) (inst->display_table));
- ((markobj) (inst->background_pixmap));
- }
- }
-
- static void
- update_face_cache_element_data (struct window *w, Lisp_Object face,
- struct face_cache_element *cachel)
- {
- if (XFACE (face)->dirty || UNBOUNDP (cachel->face))
- {
- int default_face = EQ (face, Vdefault_face);
- Lisp_Object window = Qnil;
-
- XSETWINDOW (window, w);
- cachel->face = face;
-
- /* We normally only set the _specified flags if the value was
- actually bound. The exception is for the default face where
- we always set it since it is the ultimate fallback. */
-
- #define FROB(field) \
- do { \
- Lisp_Object new_val = FACE_PROPERTY_INSTANCE (face, Q##field, window, 1); \
- int bound = 1; \
- if (UNBOUNDP (new_val)) \
- { \
- bound = 0; \
- new_val = FACE_PROPERTY_INSTANCE (face, Q##field, window, 0); \
- } \
- if (!EQ (new_val, cachel->field)) \
- { \
- cachel->field = new_val; \
- cachel->dirty = 1; \
- } \
- cachel->field##_specified = (bound || default_face); \
- } while (0)
-
- FROB (foreground);
- FROB (background);
- FROB (font);
- FROB (display_table);
- FROB (background_pixmap);
- #undef FROB
-
- #define FROB(field) \
- do { \
- Lisp_Object new_val = FACE_PROPERTY_INSTANCE (face, Q##field, window, 1); \
- int bound = 1; \
- int new_val_int; \
- if (UNBOUNDP (new_val)) \
- { \
- bound = 0; \
- new_val = FACE_PROPERTY_INSTANCE (face, Q##field, window, 0); \
- } \
- new_val_int = EQ (new_val, Qt); \
- if (cachel->field != new_val_int) \
- { \
- cachel->field = new_val_int; \
- cachel->dirty = 1; \
- } \
- cachel->field##_specified = bound; \
- } while (0)
-
- FROB (underline);
- FROB (highlight);
- FROB (dim);
- FROB (reverse);
- FROB (blinking);
- #undef FROB
- }
-
- cachel->updated = 1;
- }
-
- static void
- merge_face_cache_element_data (struct window *w, face_index findex,
- struct face_cache_element *cachel)
- {
- #define FINDEX_FIELD(field) \
- Dynarr_atp (w->face_cache_elements, findex)->field
-
- #define FROB(field) \
- do { \
- if (!cachel->field##_specified && FINDEX_FIELD (field##_specified)) \
- { \
- cachel->field = FINDEX_FIELD (field); \
- cachel->field##_specified = 1; \
- cachel->dirty = 1; \
- } \
- } while (0)
-
- FROB (foreground);
- FROB (background);
- FROB (font);
- FROB (display_table);
- FROB (background_pixmap);
- FROB (underline);
- FROB (highlight);
- FROB (dim);
- FROB (reverse);
- FROB (blinking);
- #undef FROB
- #undef FINDEX_FIELD
-
- cachel->updated = 1;
- }
-
- static void
- reset_face_cache_element (struct face_cache_element *inst)
- {
- memset (inst, 0, sizeof (struct face_cache_element));
- inst->face = Qunbound;
- inst->foreground = Qunbound;
- inst->background = Qunbound;
- inst->font = Qunbound;
- inst->display_table = Qunbound;
- inst->background_pixmap = Qunbound;
- }
-
- static void
- add_face_cache_element (struct window *w, Lisp_Object face)
- {
- struct face_cache_element new_cachel;
-
- reset_face_cache_element (&new_cachel);
- update_face_cache_element_data (w, face, &new_cachel);
- Dynarr_add (w->face_cache_elements, new_cachel);
- }
-
- face_index
- get_builtin_face_cache_index (struct window *w, Lisp_Object face)
- {
- int elt;
-
- if (noninteractive)
- return 0;
-
- for (elt = 0; elt < Dynarr_length (w->face_cache_elements); elt++)
- {
- struct face_cache_element *cachel =
- Dynarr_atp (w->face_cache_elements, elt);
-
- if (EQ (cachel->face, face))
- {
- if (!cachel->updated)
- update_face_cache_element_data (w, face, cachel);
- return elt;
- }
- }
-
- /* If we didn't find the face, add it and then return its index. */
- add_face_cache_element (w, face);
- return elt;
- }
-
- void
- reset_face_cache_elements (struct window *w)
- {
- /* #### Not initialized in batch mode for the stream device. */
- if (w->face_cache_elements)
- {
- Dynarr_reset (w->face_cache_elements);
- get_builtin_face_cache_index (w, Vdefault_face);
- get_builtin_face_cache_index (w, Vmodeline_face);
- XFRAME (w->frame)->window_face_cache_reset = 1;
- }
- }
-
- void
- mark_face_cache_elements_as_clean (struct window *w)
- {
- int elt;
-
- for (elt = 0; elt < Dynarr_length (w->face_cache_elements); elt++)
- Dynarr_atp (w->face_cache_elements, elt)->dirty = 0;
- }
-
- void
- mark_face_cache_elements_as_not_updated (struct window *w)
- {
- int elt;
-
- for (elt = 0; elt < Dynarr_length (w->face_cache_elements); elt++)
- Dynarr_atp (w->face_cache_elements, elt)->updated = 0;
- }
-
- static int
- compare_face_cache_elements (struct face_cache_element *cachel1,
- struct face_cache_element *cachel2)
- {
- if (EQ (cachel1->foreground, cachel2->foreground)
- && EQ (cachel1->background, cachel2->background)
- && EQ (cachel1->font, cachel2->font)
- && EQ (cachel1->display_table, cachel2->display_table)
- && EQ (cachel1->background_pixmap, cachel2->background_pixmap)
- && cachel1->underline == cachel2->underline
- && cachel1->highlight == cachel2->highlight
- && cachel1->dim == cachel2->dim
- && cachel1->blinking == cachel2->blinking
- && cachel1->reverse == cachel2->reverse)
- return 1;
- else
- return 0;
- }
-
-
- /*****************************************************************************
- merged face functions
- ****************************************************************************/
- static face_index
- get_merged_face_element_index (struct window *w,
- struct face_cache_element *merged_inst)
- {
- int elt;
- int cache_size = Dynarr_length (w->face_cache_elements);
-
- for (elt = 0; elt < cache_size; elt++)
- {
- struct face_cache_element *inst =
- Dynarr_atp (w->face_cache_elements, elt);
-
- /* Do not compare the face names. Merged elements will have it
- as nil and this would cause false positives. Also, by doing
- it this way if a merged instance happens to match a builtin
- face instance, we'll still return it. Why add two identical
- instances? */
- if (compare_face_cache_elements (inst, merged_inst))
- return elt;
- }
-
- /* We didn't find it so add this instance to the cache. */
- merged_inst->updated = 1;
- merged_inst->dirty = 1;
- Dynarr_add (w->face_cache_elements, *merged_inst);
- return cache_size;
- }
-
- face_index
- get_extent_fragment_face_cache_index (struct window *w,
- struct extent_fragment *ef,
- EXTENT dummy_lhe_extent)
- {
- struct face_cache_element cachel;
- int len = Dynarr_length (ef->extents);
- face_index findex;
-
- /* Optimize the default case. */
- if (len == 0)
- return DEFAULT_INDEX;
- else
- {
- int i;
- Lisp_Object window = Qnil;
- XSETWINDOW (window, w);
-
- /* Merge the faces of the extents together in order.
-
- Remember that one of the extents in the list might be our dummy
- extent representing the highlighting that is attached to some other
- extent that is currently mouse-highlighted. When an extent is
- mouse-highlighted, it is as if there are two extents there, of
- potentially different priorities: the extent being highlighted, with
- whatever face and priority it has; and an ephemeral extent in the
- `highlight' face with `mouse-highlight-priority'.
- */
-
- reset_face_cache_element (&cachel);
-
- for (i = len - 1; i >= 0; i--)
- {
- EXTENT current = Dynarr_at (ef->extents, i);
-
- if (current == dummy_lhe_extent)
- {
- /* this isn't a real extent; use the highlight face. */
- findex = get_builtin_face_cache_index (w, Vhighlight_face);
- merge_face_cache_element_data (w, findex, &cachel);
- }
- else if (!NILP (extent_face (current)))
- {
- findex = get_builtin_face_cache_index (w, extent_face (current));
- merge_face_cache_element_data (w, findex, &cachel);
- }
- }
-
- /* Now finally merge in the default face. */
- findex = get_builtin_face_cache_index (w, Vdefault_face);
- merge_face_cache_element_data (w, findex, &cachel);
-
- return get_merged_face_element_index (w, &cachel);
- }
- }
-
-
- /*****************************************************************************
- interface functions
- ****************************************************************************/
-
- /* #### This function should be converted into appropriate device methods. */
- static void
- update_EmacsFrame (Lisp_Object frame, Lisp_Object name)
- {
- struct frame *frm = XFRAME (frame);
-
- #ifdef HAVE_X_WINDOWS
- if (FRAME_IS_X (frm))
- {
- Arg av[10];
- int ac = 0;
-
- if (EQ (name, Qforeground))
- {
- Lisp_Object color = FACE_FOREGROUND (Vdefault_face, frame);
- XColor fgc;
-
- fgc = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (color));
- XtSetArg (av[ac], XtNforeground, (void *) fgc.pixel); ac++;
- }
- else if (EQ (name, Qbackground))
- {
- Lisp_Object color = FACE_BACKGROUND (Vdefault_face, frame);
- XColor bgc;
-
- bgc = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (color));
- XtSetArg (av[ac], XtNbackground, (void *) bgc.pixel); ac++;
-
- /* Really crappy way to force the modeline shadows to be
- redrawn. But effective. */
- MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (frm);
- MARK_FRAME_CHANGED (frm);
- }
- else if (EQ (name, Qfont))
- {
- Lisp_Object font = FACE_FONT (Vdefault_face, frame);
-
- XtSetArg (av[ac], XtNfont,
- (void *) FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)));
- ac++;
- }
- else
- abort ();
-
- XtSetValues (FRAME_X_TEXT_WIDGET (frm), av, ac);
-
- /* Setting the background clears the entire frame area
- including the toolbar so we force an immediate redraw of
- it. */
- if (EQ (name, Qbackground))
- MAYBE_DEVMETH (XDEVICE (frm->device), redraw_frame_toolbars, (frm));
-
- /* The intent of this code is to cause the frame size in
- characters to remain the same when the font changes, at the
- expense of changing the frame size in pixels. It's not
- totally clear that this is the right thing to do, but it's
- not clearly wrong either. */
- if (EQ (name, Qfont))
- {
- EmacsFrameRecomputeCellSize (FRAME_X_TEXT_WIDGET (frm));
- Fset_frame_size (frame,
- make_number (frm->width),
- make_number (frm->height),
- Qnil);
- }
- }
- #endif /* HAVE_X_WINDOWS */
-
- #ifdef HAVE_NEXTSTEP
- if (FRAME_IS_NS (frm))
- {
- /* This code still needs to be written */
- }
- #endif /* HAVE_NEXSTEP */
- }
-
- static void
- update_EmacsFrames (Lisp_Object locale, Lisp_Object name)
- {
- if (FRAMEP (locale))
- {
- update_EmacsFrame (locale, name);
- }
- else if (DEVICEP (locale))
- {
- Lisp_Object frm;
-
- FRAME_LOOP (frm, XDEVICE (locale))
- update_EmacsFrame (XCAR (frm), name);
- }
- else if (EQ (locale, Qglobal) || EQ (locale, Qfallback))
- {
- Lisp_Object dev, frm;
-
- DEVICE_AND_FRAME_LOOP (dev, frm)
- update_EmacsFrame (XCAR (frm), name);
- }
- }
-
- void
- update_frame_face_values (struct frame *f)
- {
- Lisp_Object frm = Qnil;
-
- XSETFRAME (frm, f);
- update_EmacsFrame (frm, Qforeground);
- update_EmacsFrame (frm, Qbackground);
- update_EmacsFrame (frm, Qfont);
- }
-
- void
- face_property_was_changed (Lisp_Object face, Lisp_Object property,
- Lisp_Object locale)
- {
- int default_face = EQ (face, Vdefault_face);
-
- /* If the locale could affect the frame value, then call
- update_EmacsFrames just in case. */
- if (default_face &&
- (EQ (property, Qforeground) ||
- EQ (property, Qbackground) ||
- EQ (property, Qfont)))
- update_EmacsFrames (locale, property);
-
- if (WINDOWP (locale))
- {
- MARK_FRAME_FACES_CHANGED (XFRAME (XWINDOW (locale)->frame));
- }
- else if (FRAMEP (locale))
- {
- MARK_FRAME_FACES_CHANGED (XFRAME (locale));
- }
- else if (DEVICEP (locale))
- {
- MARK_DEVICE_FRAMES_FACES_CHANGED (XDEVICE (locale));
- }
- else
- {
- Lisp_Object dev;
-
- DEVICE_LOOP (dev)
- MARK_DEVICE_FRAMES_FACES_CHANGED (XDEVICE (XCAR (dev)));
- }
-
- update_faces_inheritance (face, property);
- XFACE (face)->dirty = 1;
- }
-
- DEFUN ("copy-face", Fcopy_face, Scopy_face, 2, 6, 0,
- "Defines and returns a new face which is a copy of an existing one,\n\
- or makes an already-existing face be exactly like another. LOCALE,\n\
- TAG-SET, EXACT-P, and HOW-TO-ADD are as in `copy-specifier'.")
- (old_face, new_name, locale, tag_set, exact_p, how_to_add)
- Lisp_Object old_face, new_name, locale, tag_set, exact_p, how_to_add;
- {
- struct Lisp_Face *fold, *fnew;
- Lisp_Object new_face = Qnil;
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-
- old_face = Fget_face (old_face);
-
- /* We GCPRO old_face because it might be temporary, and GCing could
- occur in various places below. */
- GCPRO4 (tag_set, locale, old_face, new_face);
- /* check validity of how_to_add now. */
- (void) decode_how_to_add_specification (how_to_add);
- /* and of tag_set. */
- tag_set = decode_specifier_tag_set (tag_set);
- /* and of locale. */
- locale = decode_locale_list (locale);
-
- new_face = Ffind_face (new_name);
- if (NILP (new_face))
- {
- Lisp_Object temp;
-
- CHECK_SYMBOL (new_name, 0);
-
- /* Create the new face with the same status as the old face. */
- temp = (NILP (Fgethash (old_face, Vtemporary_faces_cache, Qnil))
- ? Qnil
- : Qt);
-
- new_face = Fmake_face (new_name, Qnil, temp);
- }
-
- fold = XFACE (old_face);
- fnew = XFACE (new_face);
-
- Fcopy_specifier (fold->foreground, fnew->foreground, locale,
- tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->background, fnew->background, locale,
- tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->font, fnew->font, locale,
- tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->display_table, fnew->display_table, locale,
- tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->background_pixmap, fnew->background_pixmap,
- locale, tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->underline, fnew->underline, locale,
- tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->highlight, fnew->highlight, locale,
- tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->dim, fnew->dim, locale,
- tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->blinking, fnew->blinking, locale,
- tag_set, exact_p, how_to_add);
- Fcopy_specifier (fold->reverse, fnew->reverse, locale,
- tag_set, exact_p, how_to_add);
- /* #### should it copy the individual specifiers, if they exist? */
- fnew->plist = Fcopy_sequence (fold->plist);
-
- UNGCPRO;
-
- return new_name;
- }
-
-
- void
- init_faces (void)
- {
- if (!initialized)
- return;
-
- Vpermanent_faces_cache = make_lisp_hashtable (10, 0, 0, HASHTABLE_NONWEAK);
- Vtemporary_faces_cache = make_lisp_hashtable (0, 0, 0, HASHTABLE_WEAK);
-
- /* Create the default face now so we know what it is immediately. */
- Vdefault_face = Qnil; /* so that Fmake_face() doesn't set up a bogus
- default value */
- Vdefault_face = Fmake_face (Qdefault, build_string ("default face"),
- Qnil);
-
- /* Now create and initialize the rest of the built-in faces. */
- call0_with_handler (Qreally_early_error_handler, Qinit_faces);
-
- /* If Fget_face signals an error bad, bad things are going to
- happen. That should only be possible if someone decided to stop
- creating these faces in init-faces. Bad, bad someone. */
- Vmodeline_face = Fget_face (Qmodeline);
- Vhighlight_face = Fget_face (Qhighlight);
- Vleft_margin_face = Fget_face (Qleft_margin);
- Vright_margin_face = Fget_face (Qright_margin);
-
- /* Provide some last-resort fallbacks to avoid utter fuckage if
- someone provides invalid values for the global specifications. */
- set_specifier_fallback (Fget (Vdefault_face, Qforeground, Qnil),
- list1 (Fcons (Qnil,
- build_string ("black"))));
- set_specifier_fallback (Fget (Vdefault_face, Qbackground, Qnil),
- list1 (Fcons (Qnil,
- build_string ("white"))));
-
- /* #### We may want to have different fallback values if NeXTstep
- support is compiled in. */
- #ifdef HAVE_X_WINDOWS
- {
- char *fonts[30];
- int n = 0;
- Lisp_Object inst_list = Qnil;
-
- /* The same gory list from x-faces.el.
- (#### Perhaps we should remove the stuff from x-faces.el
- and only depend on this stuff here? That should work.)
- */
- fonts[n++] = "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*";
- fonts[n++] = "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*";
- fonts[n++] = "-*-courier-*-r-*-*-*-120-*-*-*-*-iso8859-*";
- fonts[n++] = "-*-*-medium-r-*-*-*-120-*-*-m-*-iso8859-*";
- fonts[n++] = "-*-*-medium-r-*-*-*-120-*-*-c-*-iso8859-*";
- fonts[n++] = "-*-*-*-r-*-*-*-120-*-*-m-*-iso8859-*";
- fonts[n++] = "-*-*-*-r-*-*-*-120-*-*-c-*-iso8859-*";
- fonts[n++] = "-*-*-*-r-*-*-*-120-*-*-*-*-iso8859-*";
- fonts[n++] = "-*-*-medium-r-*-*-*-120-*-*-m-*-*-*";
- fonts[n++] = "-*-*-medium-r-*-*-*-120-*-*-c-*-*-*";
- fonts[n++] = "-*-*-*-r-*-*-*-120-*-*-m-*-*-*";
- fonts[n++] = "-*-*-*-r-*-*-*-120-*-*-c-*-*-*";
- fonts[n++] = "-*-*-*-r-*-*-*-120-*-*-*-*-*-*";
- fonts[n++] = "-*-*-*-*-*-*-*-120-*-*-*-*-*-*";
- fonts[n++] = "*";
-
- for (--n; n >= 0; --n)
- inst_list = Fcons (Fcons (list1 (Qx), build_string (fonts[n])),
- inst_list);
- set_specifier_fallback (Fget (Vdefault_face, Qfont, Qnil), inst_list);
- }
- #else
- /* #### This assumes that a font of nil is an OK instantiator, which
- may not be the case. */
- set_specifier_fallback (Fget (Vdefault_face, Qfont, Qnil), Qnil);
- #endif
-
- set_specifier_fallback (Fget (Vdefault_face, Qunderline, Qnil),
- list1 (Fcons (Qnil, Qnil)));
- set_specifier_fallback (Fget (Vdefault_face, Qhighlight, Qnil),
- list1 (Fcons (Qnil, Qnil)));
- set_specifier_fallback (Fget (Vdefault_face, Qdim, Qnil),
- list1 (Fcons (Qnil, Qnil)));
- set_specifier_fallback (Fget (Vdefault_face, Qblinking, Qnil),
- list1 (Fcons (Qnil, Qnil)));
- set_specifier_fallback (Fget (Vdefault_face, Qreverse, Qnil),
- list1 (Fcons (Qnil, Qnil)));
- }
-
- void
- syms_of_faces (void)
- {
- /* Qdefault defined in general.c */
- defsymbol (&Qmodeline, "modeline");
- defsymbol (&Qleft_margin, "left-margin");
- defsymbol (&Qright_margin, "right-margin");
-
- defsubr (&Sfacep);
- defsubr (&Sfind_face);
- defsubr (&Sget_face);
- defsubr (&Sface_name);
- defsubr (&Sface_ascent);
- defsubr (&Sface_descent);
- defsubr (&Sface_width);
- defsubr (&Sface_list);
- defsubr (&Sextent_face);
- defsubr (&Sset_extent_face);
- defsubr (&Smake_face);
- defsubr (&Scopy_face);
-
- defsymbol (&Qface, "face");
- defsymbol (&Qfacep, "facep");
- defsymbol (&Qforeground, "foreground");
- defsymbol (&Qbackground, "background");
- /* Qfont defined in general.c */
- defsymbol (&Qdisplay_table, "display-table");
- defsymbol (&Qbackground_pixmap, "background-pixmap");
- defsymbol (&Qunderline, "underline");
- /* Qhighlight, Qreverse defined in general.c */
- defsymbol (&Qdim, "dim");
- defsymbol (&Qblinking, "blinking");
-
- defsymbol (&Qinit_face_from_resources, "init-face-from-resources");
- defsymbol (&Qinit_global_faces, "init-global-faces");
- defsymbol (&Qinit_device_faces, "init-device-faces");
- defsymbol (&Qinit_frame_faces, "init-frame-faces");
- defsymbol (&Qinit_faces, "init-faces");
- }
-
- void
- vars_of_faces (void)
- {
- staticpro (&Vpermanent_faces_cache);
- Vpermanent_faces_cache = Qnil;
- staticpro (&Vtemporary_faces_cache);
- Vtemporary_faces_cache = Qnil;
-
- staticpro (&Vdefault_face);
- Vdefault_face = Qnil;
- staticpro (&Vmodeline_face);
- Vmodeline_face = Qnil;
- staticpro (&Vhighlight_face);
- Vhighlight_face = Qnil;
-
- staticpro (&Vleft_margin_face);
- Vleft_margin_face = Qnil;
- staticpro (&Vright_margin_face);
- Vright_margin_face = Qnil;
- }
-